package com.loan.web.pdf;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.loan.common.core.domain.AjaxResult;
import com.loan.common.pdf.PDFUtil;
import com.loan.common.utils.StringUtils;
import com.loan.system.create.domain.AssistPdfBaseConf;
import com.loan.system.create.domain.AssistPdfContentConf;
import com.loan.system.create.domain.AssistPdfTableConf;
import com.loan.system.create.service.IAssistPdfBaseConfService;
import com.loan.system.create.service.IAssistPdfContentConfService;
import com.loan.system.create.service.IAssistPdfSearchBaseService;
import com.loan.system.create.service.IAssistPdfTableConfService;
import com.loan.system.domain.work.domain.CreatePdfReq;
import com.loan.system.domain.work.domain.JhPdfDomain;
import com.loan.system.domain.work.domain.NhPdfDomain;
import com.loan.system.domain.work.domain.TableValue;
import com.loan.system.domain.work.domain.vo.JhReq;
import com.loan.system.domain.work.domain.vo.NhReq;
import com.loan.web.utils.ExportBankUtil;
import com.loan.web.utils.ExtractorBankUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/pdfTest")
public class TestPdfController {

    @Autowired
    private IAssistPdfBaseConfService assistPdfBaseConfService;
    @Autowired
    private IAssistPdfContentConfService assistPdfContentConfService;
    @Autowired
    private IAssistPdfTableConfService assistPdfTableConfService;
    @Autowired
    private IAssistPdfSearchBaseService assistPdfSearchBaseService;
    @Autowired
    private ExtractorBankUtil extractorBankUtil;
    @Autowired
    private ExportBankUtil exportBankUtil;

    @PostMapping("/testCreatePdf")
    public void createPdfFile(@RequestBody CreatePdfReq pdfReq) throws IOException {
        // 生成的PDF文件地址
        log.info("生成PDF文件信息...");
        try {
            File file = new File("E:\\GCH\\testFileColl\\assionFileTemp\\inOutDetail\\pdftest.pdf");
            OutputStream outputStream = new FileOutputStream(file);

            // 定义全局的字体静态变量
            BaseFont bf;
            Font font = null;
            Font cellContentFont = null;
            AssistPdfBaseConf baseConf = assistPdfBaseConfService.selectAssistPdfBaseConfById(pdfReq.getTypeId());
            String fontPath = baseConf.getPdfBaseFontPath();
            // 最大宽度
            //创建字体
            bf = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            //使用字体并给出颜色
            font = new Font(bf, baseConf.getPdfBaseTitleFontSize(), Integer.valueOf(baseConf.getPdfBaseTitleFontStyle()), BaseColor.BLACK);
            // 不同字体（这里定义为同一种字体：包含不同字号、不同style）
            BaseFont bfChinese = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            cellContentFont = new Font(bfChinese, baseConf.getPdfBaseGlobalFontSize(), Integer.valueOf(baseConf.getPdfBaseGlobalFontStyle()));

            // 设置PDF大小
            Document document = new Document(new RectangleReadOnly(Float.valueOf(baseConf.getPdfPaperWidth()), Float.valueOf(baseConf.getPdfPaperHeight()))); // A4纸张
            //设置页边距  60:左边距，60：右边距，72：上边距，72：下边距
            document.setMargins(baseConf.getPdfPaperLeftMargin(), baseConf.getPdfPaperRightMargin(), baseConf.getPdfPaperTopMargin(), baseConf.getPdfPaperBottomMargin());
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            //添加页码
            // writer.setPageEvent(new PdfPageUtil());
            //打开生成的pdf文件
            document.open();
            //设置内容
            Paragraph paragraph = new Paragraph(baseConf.getPdfBaseTitle(), font);
            paragraph.setAlignment(Integer.valueOf(baseConf.getPdfBaseTitleAlign())); // 居中显示
            //引用内容
            document.add(paragraph);

            PdfPTable tb = new PdfPTable(Math.toIntExact(baseConf.getPdfBaseDescNum()));
            tb.setWidthPercentage(100);

            // 查询描述内容配置信息
            log.info("查询描述文件配置信息...");
            AssistPdfContentConf contCont = new AssistPdfContentConf();
            contCont.setBaseConfId(baseConf.getId());
            List<AssistPdfContentConf> contentList = assistPdfContentConfService.selectAssistPdfContentConfList(contCont);
            List<AssistPdfContentConf> contentSortList = contentList.stream().sorted(Comparator.comparingInt(AssistPdfContentConf::getPdfContentSort)).collect(Collectors.toList());
            if (contentSortList != null && contentSortList.size() > 0) {
                for (AssistPdfContentConf contentConf : contentSortList) {
                    String pdfContentTitle = contentConf.getPdfContentTitle();
                    if (pdfContentTitle.contains("{userName}")) {
                        pdfContentTitle = pdfContentTitle.replace("{userName}", pdfReq.getUserName());
                    }
                    if (pdfContentTitle.contains("{accountNo}")) {
                        if (StringUtils.isBlank(pdfReq.getAccountNo())) {
                            String accountNo = (getRandomValue() + getRandomValue()).substring(1);
                            pdfContentTitle = pdfContentTitle.replace("{accountNo}", accountNo);
                        } else {
                            pdfContentTitle = pdfContentTitle.replace("{accountNo}", pdfReq.getAccountNo());
                        }
                    }
                    if (pdfContentTitle.contains("{serialNo}")) {
                        if (StringUtils.isBlank(pdfReq.getSerialNo())) {
                            // 为空，则随机生成
                            String time = pdfReq.getEndTime().replace("-", "");
                            time = time.substring(2) + new SimpleDateFormat("HHmmss").format(new Date());
                            time = time + getRandomValue().substring(2);
                            pdfContentTitle = pdfContentTitle.replace("{serialNo}", time);
                        } else {
                            pdfContentTitle = pdfContentTitle.replace("{serialNo}", pdfReq.getSerialNo());
                        }
                    }
                    if (pdfContentTitle.contains("{startTime}")) {
                        pdfContentTitle = pdfContentTitle.replace("{startTime}", pdfReq.getStartTime().replace("-", ""));
                    }
                    if (pdfContentTitle.contains("{endTime}")) {
                        pdfContentTitle = pdfContentTitle.replace("{endTime}", pdfReq.getEndTime().replace("-", ""));
                    }
                    PDFUtil.getCellValue(tb, pdfContentTitle, cellContentFont, null, Integer.parseInt(contentConf.getPdfContentAlign()));
                }
                document.add(tb);
            }

            log.info("添加图片logo到PDF文件中...");
            // 添加图片到PDF文件中
            PDFUtil.addImg(document, baseConf.getPdfBaseImagePath(), 50f, 50f, 460f, 710f);

            AssistPdfTableConf tableConf = new AssistPdfTableConf();
            tableConf.setBaseConfId(baseConf.getId());
            List<AssistPdfTableConf> tableList = assistPdfTableConfService.selectAssistPdfTableConfList(tableConf);
            List<AssistPdfTableConf> tableSortList = tableList.stream().sorted(Comparator.comparingInt(AssistPdfTableConf::getPdfTableSort)).collect(Collectors.toList());
            if (tableSortList != null && tableSortList.size() > 0) {
                log.info("查询配置信息，并生成PDF内容...");
                float[] width = new float[tableSortList.size()];
                for (int i = 0; i < tableSortList.size(); i++) {
                    width[i] = Float.valueOf(tableSortList.get(i).getPdfTableCellWidth());
                }
                PdfPTable table1 = new PdfPTable(width);
                table1.setSpacingBefore(4f);
                // 设置表格宽度为100%
                table1.setWidthPercentage(100.0F);
                table1.getDefaultCell().setHorizontalAlignment(1);
                // 设置表格上边框
                log.info("设置表格表头上边框信息...");
                for (int i = 0; i < tableSortList.size(); i++) {
                    PdfPCell cell = new PdfPCell(new Paragraph("", font));
                    cell.setFixedHeight(1); // 设置高度
                    cell.setHorizontalAlignment(0); // 设置对齐方式 默认水平左对齐
                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直对齐
                    cell.disableBorderSide(13); // 设置边框信息 默认只显示上下
                    table1.addCell(cell);
                }
                document.add(table1);

                PdfPTable table3 = new PdfPTable(width);
                table3.setSpacingBefore(0f);
                // 设置表格宽度为100%
                table3.setWidthPercentage(100.0F);
                table3.setHeaderRows(1);
                table3.getDefaultCell().setHorizontalAlignment(1);
                log.info("设置表格表头标题信息...");
                for (AssistPdfTableConf tc : tableSortList) {
                    PDFUtil.getCellTitleValue(table3, tc.getPdfTableTitle(), cellContentFont, Integer.parseInt(tc.getPdfTableTitleAlign()), 15);
                }
                // 设置表格表头下边框
                log.info("设置表格表头下边框信息...");
                for (int i = 0; i < tableSortList.size(); i++) {
                    PdfPCell cell = new PdfPCell(new Paragraph("", font));
                    cell.setFixedHeight(1); // 设置高度
                    cell.setHorizontalAlignment(0); // 设置对齐方式 默认水平左对齐
                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直对齐
                    cell.disableBorderSide(14); // 设置边框信息 默认只显示上下
                    table3.addCell(cell);
                }

                List<TableValue> tableValueList = this.setTableValue(pdfReq);

                // 随机生成表格内容数据
                log.info("随机抓取生成数据到PDF表格中...");
                int flag = 0;
                List<String> fieldValueList = this.getFieldValue(tableValueList);
                for (String value : fieldValueList) {
                    PDFUtil.getCellValue(table3, value, cellContentFont, Integer.parseInt(tableSortList.get(flag).getPdfTableValueBorderConf()),
                            Integer.parseInt(tableSortList.get(flag).getPdfTableValueAlign()));
                    if ((flag + 1) == tableSortList.size()) {
                        // 大小相同时，则置0
                        flag = 0;
                    } else {
                        flag++;
                    }
                }
                document.add(table3);
                log.info("PDF文件生成完成...");
            }
            //关闭文档
            document.close();
        } catch (DocumentException e) {
            log.error("生成PDF文件失败: {}", e.getMessage());
            log.error(e.getMessage(), e);
        }
    }

    @PostMapping("/getRandomTableValue")
    public AjaxResult getRandomTableValue(@RequestBody CreatePdfReq pdfReq) {
        // List<TableValue> tableValueList = this.setTableValue(pdfReq);
        Map<String, List<Float>> map = new HashMap<>();
        List<Float> inMoney = this.getRandomFloatMoneyValue("收入", pdfReq.getOriginalMoney(), pdfReq.getTotalInMoney(), pdfReq.getInNum());
        List<Float> outMoney = this.getRandomFloatMoneyValue("支出", 0, pdfReq.getTotalOutMoney(), pdfReq.getDetailNums() - pdfReq.getInNum());
        map.put("inList", inMoney);
        map.put("outList", outMoney);
        return AjaxResult.success(map);
    }

    /**
     * 获取收/入生成的明细数据
     *
     * @param pdfReq
     * @return
     */
    @PostMapping("/getDealedValueList")
    public AjaxResult getDealedValueList(@RequestBody CreatePdfReq pdfReq) {
        Map<String, List<TableValue>> map = new HashMap<>();
        List<TableValue> inValueList = new ArrayList<>();
        List<TableValue> outValueList = new ArrayList<>();

        List<TableValue> tableValueList = this.setTableValue(pdfReq);
        if (tableValueList != null && tableValueList.size() > 0) {
            for (TableValue tableValue : tableValueList) {
                String transactionMoney = tableValue.getTransactionMoney();
                if (StringUtils.contains(transactionMoney, ".")) {
                    transactionMoney = transactionMoney.split("\\.")[0]; // 取小数点前的数值
                }
                tableValue.setTransactionMoneyInt(Integer.parseInt(transactionMoney));
                if (StringUtils.contains(tableValue.getTransactionMoney(), "+")) {
                    // 收入标识
                    inValueList.add(tableValue);
                } else {
                    // 支出标识
                    outValueList.add(tableValue);
                }
            }
        }
        map.put("inValueList", inValueList);
        map.put("outValueList", outValueList);
        return AjaxResult.success(map);
    }

    /**
     * 生成PDF文件
     *
     * @param pdfReq
     * @throws IOException
     */
    @PostMapping("/createFileByData")
    public AjaxResult createFileByData(@RequestBody CreatePdfReq pdfReq) throws Exception {
        if (StringUtils.equals(pdfReq.getType(), "NH")) {
            pdfReq.setTypeId(1l);
            return exportBankUtil.createNhPdfTemp(pdfReq);
        }
        return AjaxResult.success();
    }

    /**
     * 提取Bank数据并检索入库
     *
     * @return
     */
    @PostMapping("/extractorBankToRecords/{bankType}")
    public AjaxResult extractorBankToRecords(@PathVariable("bankType") String bankType,
                                             @RequestBody MultipartFile file) throws Exception {
        //加载PDF文档
        String filePath = "E:\\GCH\\bank_detail.pdf";
        File f = new File(filePath);
        file.transferTo(f);
        if (StringUtils.equals(bankType, "JH")) {
            // 调用JH
            extractorBankUtil.extractorJhBankData(f.getAbsolutePath());
        } else if (StringUtils.equals(bankType, "NH")) {
            // 调用NH
            extractorBankUtil.extractorNhBankData(f);
        } else if (StringUtils.equals(bankType, "WX")) {
            // 调用WX
            extractorBankUtil.extractorWxBankData(f.getAbsolutePath());
        } else if (StringUtils.equals(bankType, "ZFB")) {
            // 调用ZFB
            extractorBankUtil.extractorZfbBankData(f.getAbsolutePath());
        } else {
            // 未知类型
            log.info("未知类型：{}", bankType);
        }
        return AjaxResult.success();
    }

    /**
     * 根据入参拉取要生成的明细数据
     *
     * @param pdfReq
     * @return
     */
    @PostMapping("/getDetailValueList")
    public AjaxResult getDetailValueList(@RequestBody CreatePdfReq pdfReq) {
        String type = pdfReq.getType();
        if (StringUtils.equals(type, "NH")) {
            Map<String, List<NhPdfDomain>> map = new HashMap<>();
            List<NhPdfDomain> inValueList = new ArrayList<>();
            List<NhPdfDomain> outValueList = new ArrayList<>();
            List<NhPdfDomain> list = extractorBankUtil.compNhDataDetail(pdfReq.getStartTime(), pdfReq.getEndTime(), pdfReq.getOriginalMoney(), pdfReq.getTotalInMoney(), pdfReq.getTotalOutMoney());

            list.forEach(item -> {
                if (StringUtils.startsWith(item.getTransactionAmount(), "+")) {
                    // 收
                    inValueList.add(item);
                } else {
                    outValueList.add(item);
                }
            });
            map.put("inValueList", inValueList);
            map.put("outValueList", outValueList);
            return AjaxResult.success(map);
        } else if (StringUtils.equals(type, "JH")) {
            Map<String, List<JhPdfDomain>> map = new HashMap<>();
            List<JhPdfDomain> inValueList = new ArrayList<>();
            List<JhPdfDomain> outValueList = new ArrayList<>();
            List<JhPdfDomain> list = extractorBankUtil.compJhDataDetail(pdfReq.getSeqNo(), pdfReq.getStartTime(), pdfReq.getEndTime(), pdfReq.getOriginalMoney(), pdfReq.getTotalInMoney(), pdfReq.getTotalOutMoney());

            list.forEach(item -> {
                if (StringUtils.equals(item.getTransactionType(), "+")) {
                    // 收
                    inValueList.add(item);
                } else {
                    outValueList.add(item);
                }
            });
            map.put("inValueList", inValueList);
            map.put("outValueList", outValueList);
            return AjaxResult.success(map);
        }
        return AjaxResult.error();
    }

    @PostMapping("/getNhData")
    public AjaxResult getNhData(@RequestBody NhReq nhReq) {
        List<NhPdfDomain> list = extractorBankUtil.compNhDataDetail(nhReq.getStartTime(), nhReq.getEndTime(), nhReq.getOriginalMoney(), nhReq.getInMoney(), nhReq.getOutMoney());
        return AjaxResult.success(list);
    }

    @PostMapping("/getJhData")
    public AjaxResult getJhData(@RequestBody JhReq jhReq) {
        List<JhPdfDomain> list = extractorBankUtil.compJhDataDetail(jhReq.getSeqNo(), jhReq.getStartTime(), jhReq.getEndTime(), jhReq.getOriginalMoney(), jhReq.getTotalInMoney(), jhReq.getTotalOutMoney());
        return AjaxResult.success(list);
    }

    private List<TableValue> setTableValue(CreatePdfReq pdfReq) {
        List<TableValue> tableValueList = new ArrayList<>();
        String[] inDesc = {"代付", "转存"}; // 入账交易摘要
        String[] outDesc = {"转支", "微信支付", "支付宝", "财付通"}; // 出账交易摘要
        String[] opposition = {"财付通支付科技有限公司", "唐春成", "微信转账", "扫⼆维码付款", "郑州碧兔喜商贸有限公司", "驻⻢店市三棵树酒店有限公司"}; // 对手信息
        String[] note = {"唐春成", "微信转账", "扫⼆维码付款", "郑州碧兔喜商贸有限公司", "驻⻢店市三棵树酒店有限公司"}; // 交易附言
        List<String> searchList = assistPdfSearchBaseService.selectAllList();
        Random random = new Random();
        int num = pdfReq.getDetailNums(); // 生成103条明细
        Map<String, List<String>> map = PDFUtil.getRandomDateTimeList(pdfReq.getStartTime(), pdfReq.getEndTime(), num);
        List<String> dateStrList = map.get("dateStrList");
        List<String> timeStrList = map.get("timeStrList");
        // 获取随机金额
        log.info("获取随机入出金额...");
        Integer money = pdfReq.getOriginalMoney(); // 原始余额
        int inNum = pdfReq.getInNum();
        int outNum = num - inNum;
        List<String> moneyList = new ArrayList<>();
        List<String> inMoneyList = this.getRandomMoneyValue("收入", money, pdfReq.getTotalInMoney(), inNum);
        List<String> outMoneyList = this.getRandomMoneyValue("支出", 0, pdfReq.getTotalOutMoney(), outNum);
        moneyList.addAll(inMoneyList);
        moneyList.addAll(outMoneyList);
        log.info("随机排序前：{}", moneyList);
        Collections.shuffle(moneyList);
        log.info("随机排序后：{}", moneyList);

        for (int i = 0; i < dateStrList.size(); i++) {
            String moneyStr = moneyList.get(i);
            boolean addFlag = StringUtils.contains(moneyStr, "+");
            String moneyValue = moneyStr.replace("+", "").replace("-", "");
            if (addFlag) {
                money += Integer.parseInt(moneyValue);
            } else {
                Integer tempMoney = money;
                Integer orginMoney = Integer.parseInt(moneyValue);
                money -= orginMoney;
                while (money <= 0) {
                    orginMoney = orginMoney / 2;
                    money = tempMoney - orginMoney;
                    moneyList.set(i, "-" + orginMoney);
                    moneyStr = "-" + orginMoney;
                }
            }
            TableValue tableValue = new TableValue();
            tableValue.setTransactionDate(dateStrList.get(i));
            tableValue.setTransactionTime(timeStrList.get(i));
            tableValue.setTransactionDesc(addFlag ? inDesc[random.nextInt(inDesc.length)] : outDesc[random.nextInt(outDesc.length)]);
            tableValue.setTransactionMoney(moneyStr + ".00");
            tableValue.setCurrentBalance(String.valueOf(money) + ".00");
            tableValue.setOppositionInfo(searchList.get(random.nextInt(searchList.size() - 1)));
            tableValue.setLogNo(this.getRandomValue());
            tableValue.setTradingChannels(addFlag ? "超级网银" : "电子商务");
            tableValue.setTransactionNote(note[random.nextInt(note.length)]);
            tableValue.setSortNo(i); // 设置序号
            tableValueList.add(tableValue);
        }
        return tableValueList;
    }

    /**
     * 根据反射获取属性值
     *
     * @param list
     * @return
     */
    private List<String> getFieldValue(List<TableValue> list) {
        List<String> valueList = new ArrayList<>();
        try {
            if (list != null && list.size() > 0) {
                for (TableValue tableValue : list) {
                    Class<? extends TableValue> tableValueClazz = tableValue.getClass();
                    Field[] fields = tableValueClazz.getDeclaredFields();
                    for (Field field : fields) {
                        field.setAccessible(true);
                        String name = field.getName();
                        if (StringUtils.equalsAny(name, "transactionMoneyInt", "sortNo")) {
                            continue;
                        }
                        String value = String.valueOf(field.get(tableValue));
                        // log.info("{}：{}", name, value);
                        valueList.add(value);
                    }
                }
            }
        } catch (IllegalAccessException e) {
            log.error("反射获取属性值异常:{}", e.getMessage());
            log.error(e.getMessage(), e);
        }
        return valueList;
    }

    /**
     * 获取9位随机数字
     *
     * @return
     */
    private String getRandomValue() {
        Random random = new Random();
        int randomNumber = 100000000 + random.nextInt(900000000); // 生成9位随机数
        return String.valueOf(randomNumber);
    }

    /**
     * @param inOrOut      收入/支出
     * @param excludeMoney 已过滤的金额
     * @param total        总金额
     * @param splitCount   个数
     */
    private List<String> getRandomMoneyValue(String inOrOut, Integer excludeMoney, int total, int splitCount) {
        List<String> moneyStrList = new ArrayList<>();
        double maxValue = (total / splitCount) * 1.5; // 生成金额的最大范围(期待金额平均值的1.5倍)
        Integer max = (int) maxValue;
        Integer min = 20;

        log.info("需要的{}总金额: {}", inOrOut, total);
        log.info("已过滤{}总金额: {}", inOrOut, excludeMoney);
        log.info("除过滤共有{}个数: {}", inOrOut, splitCount);
        log.info("最小金额: {}", min);
        log.info("最大金额: {}", max);
        Integer tempTotal = total;

        List<Integer> moneyList = new ArrayList<Integer>();
        Random random = new Random();
        for (int i = 0; i < splitCount; i++) {
            int num = 0;
            do {
                num = random.nextInt(max);
            } while (num > max || num < min);
            total -= num;
            moneyList.add(num);
        }

        int check_num = 0;
        int check_num_two = 0;

        log.info(Arrays.toString(moneyList.toArray()));

        for (int x : moneyList) {
            check_num = check_num + x;
        }
        int dealMoneyTotal = check_num + excludeMoney;
        log.info("第一次验证总和: {}", dealMoneyTotal);
        if (dealMoneyTotal < tempTotal) {
            log.info("验证总和: {} 小于预期金额，则进行处理...", dealMoneyTotal);
            int stillNeedMoney = (tempTotal - dealMoneyTotal) + (tempTotal / 10); // 仍需的金额数
            int avgAddMoney = stillNeedMoney / moneyList.size(); // 平均每笔收入要增加的金额数
            for (int i = 0; i < moneyList.size(); i++) {
                Integer orginInt = moneyList.get(i);
                Integer newInt = orginInt + avgAddMoney;
                if (newInt > 100 && newInt < 10000) {
                    Integer dealInt = (newInt / 10) * 10;
                    moneyList.set(i, dealInt);
                }
                if (newInt > 10000) {
                    Integer dealInt = (newInt / 100) * 100;
                    moneyList.set(i, dealInt);
                }
            }
        }
        tempTotal = tempTotal + (tempTotal / 10); // 预期值的10%
        if (dealMoneyTotal > tempTotal) {
            log.info("验证总和: {} 大于预期金额的10%，则进行处理...", dealMoneyTotal);
            int stillNeedMoney = (dealMoneyTotal - tempTotal); // 多余的金额数
            int avgDivMoney = stillNeedMoney / moneyList.size(); // 平均每笔支出要减少的金额数
            for (int i = 0; i < moneyList.size(); i++) {
                Integer orginInt = moneyList.get(i);
                if (orginInt > avgDivMoney) {
                    Integer newInt = orginInt - avgDivMoney;
                    if (newInt > 100 && newInt < 10000) {
                        Integer dealInt = (newInt / 10) * 10;
                        moneyList.set(i, dealInt);
                    }
                    if (newInt > 10000) {
                        Integer dealInt = (newInt / 100) * 100;
                        moneyList.set(i, dealInt);
                    }
                }
            }
        }
        log.info("处理金额位数...");
        for (int i = 0; i < moneyList.size(); i++) {
            Integer orginMoney = moneyList.get(i);
            if (orginMoney > 100 && orginMoney < 10000) {
                Integer dealInt = (orginMoney / 10) * 10;
                moneyList.set(i, dealInt);
            }
            if (orginMoney > 10000) {
                Integer dealInt = (orginMoney / 100) * 100;
                moneyList.set(i, dealInt);
            }
        }
        log.info("处理结果：{}", Arrays.toString(moneyList.toArray()));
        Integer maxMoney = Collections.max(moneyList);
        log.info("处理结果最大值：{}", maxMoney);
        for (int x : moneyList) {
            check_num_two = check_num_two + x;
        }
        log.info("再次验证总和: {}", check_num_two + excludeMoney);
        for (Integer i : moneyList) {
            String moneyStr = StringUtils.equals(inOrOut, "收入") ? ("+" + i) : ("-" + i);
            moneyStrList.add(moneyStr);
        }
        return moneyStrList;
    }

    /**
     * @param inOrOut      收入/支出
     * @param excludeMoney 已过滤的金额
     * @param total        总金额
     * @param splitCount   个数
     */
    private List<Integer> getRandomIntegerMoneyValue(String inOrOut, Integer excludeMoney, int total, int splitCount) {
        List<String> moneyStrList = new ArrayList<>();
        double maxValue = (total / splitCount) * 1.5; // 生成金额的最大范围(期待金额平均值的1.5倍)
        Integer max = (int) maxValue;
        Integer min = 20;

        log.info("需要的{}总金额: {}", inOrOut, total);
        log.info("已过滤{}总金额: {}", inOrOut, excludeMoney);
        log.info("除过滤共有{}个数: {}", inOrOut, splitCount);
        log.info("最小金额: {}", min);
        log.info("最大金额: {}", max);
        Integer tempTotal = total;

        List<Integer> moneyList = new ArrayList<Integer>();
        Random random = new Random();
        for (int i = 0; i < splitCount; i++) {
            int num = 0;
            do {
                num = random.nextInt(max);
            } while (num > max || num < min);
            total -= num;
            moneyList.add(num);
        }

        int check_num = 0;
        int check_num_two = 0;

        log.info(Arrays.toString(moneyList.toArray()));

        for (int x : moneyList) {
            check_num = check_num + x;
        }
        int dealMoneyTotal = check_num + excludeMoney;
        log.info("第一次验证总和: {}", dealMoneyTotal);
        if (dealMoneyTotal < tempTotal) {
            log.info("验证总和: {} 小于预期金额，则进行处理...", dealMoneyTotal);
            int stillNeedMoney = (tempTotal - dealMoneyTotal) + (tempTotal / 10); // 仍需的金额数
            int avgAddMoney = stillNeedMoney / moneyList.size(); // 平均每笔收入要增加的金额数
            for (int i = 0; i < moneyList.size(); i++) {
                Integer orginInt = moneyList.get(i);
                Integer newInt = orginInt + avgAddMoney;
                if (newInt > 100 && newInt < 10000) {
                    Integer dealInt = (newInt / 10) * 10;
                    moneyList.set(i, dealInt);
                }
                if (newInt > 10000) {
                    Integer dealInt = (newInt / 100) * 100;
                    moneyList.set(i, dealInt);
                }
            }
        }
        tempTotal = tempTotal + (tempTotal / 10); // 预期值的10%
        if (dealMoneyTotal > tempTotal) {
            log.info("验证总和: {} 大于预期金额的10%，则进行处理...", dealMoneyTotal);
            int stillNeedMoney = (dealMoneyTotal - tempTotal); // 多余的金额数
            int avgDivMoney = stillNeedMoney / moneyList.size(); // 平均每笔支出要减少的金额数
            for (int i = 0; i < moneyList.size(); i++) {
                Integer orginInt = moneyList.get(i);
                if (orginInt > avgDivMoney) {
                    Integer newInt = orginInt - avgDivMoney;
                    if (newInt > 100 && newInt < 10000) {
                        Integer dealInt = (newInt / 10) * 10;
                        moneyList.set(i, dealInt);
                    }
                    if (newInt > 10000) {
                        Integer dealInt = (newInt / 100) * 100;
                        moneyList.set(i, dealInt);
                    }
                }
            }
        }
        log.info("处理金额位数...");
        for (int i = 0; i < moneyList.size(); i++) {
            Integer orginMoney = moneyList.get(i);
            if (orginMoney > 100 && orginMoney < 10000) {
                Integer dealInt = (orginMoney / 10) * 10;
                moneyList.set(i, dealInt);
            }
            if (orginMoney > 10000) {
                Integer dealInt = (orginMoney / 100) * 100;
                moneyList.set(i, dealInt);
            }
        }
        log.info("处理结果：{}", Arrays.toString(moneyList.toArray()));
        Integer maxMoney = Collections.max(moneyList);
        log.info("处理结果最大值：{}", maxMoney);
        for (int x : moneyList) {
            check_num_two = check_num_two + x;
        }
        log.info("再次验证总和: {}", check_num_two + excludeMoney);
        for (Integer i : moneyList) {
            String moneyStr = StringUtils.equals(inOrOut, "收入") ? ("+" + i) : ("-" + i);
            moneyStrList.add(moneyStr);
        }
        return moneyList;
    }

    /**
     * @param inOrOut      收入/支出
     * @param excludeMoney 已过滤的金额
     * @param total        总金额
     * @param splitCount   个数
     */
    private List<Float> getRandomFloatMoneyValue(String inOrOut, Integer excludeMoney, int total, int splitCount) {
        List<String> moneyStrList = new ArrayList<>();
        double maxValue = (total / splitCount) * 1.5; // 生成金额的最大范围(期待金额平均值的1.5倍)
        Integer max = (int) maxValue;
        Integer min = 20;

        log.info("需要的{}总金额: {}", inOrOut, total);
        log.info("已过滤{}总金额: {}", inOrOut, excludeMoney);
        log.info("除过滤共有{}个数: {}", inOrOut, splitCount);
        log.info("最小金额: {}", min);
        log.info("最大金额: {}", max);
        Integer tempTotal = total;

        List<Float> moneyList = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < splitCount; i++) {
            int num = 0;
            do {
                num = random.nextInt(max);
            } while (num > max || num < min);
            total -= num;
            moneyList.add(Float.valueOf(num));
        }

        float check_num = 0;
        float check_num_two = 0;

        log.info(Arrays.toString(moneyList.toArray()));

        for (float x : moneyList) {
            check_num = check_num + x;
        }
        float dealMoneyTotal = check_num + excludeMoney;
        log.info("第一次验证总和: {}", dealMoneyTotal);
        if (dealMoneyTotal < tempTotal) {
            log.info("验证总和: {} 小于预期金额，则进行处理...", dealMoneyTotal);
            float stillNeedMoney = (tempTotal - dealMoneyTotal) + (tempTotal / 10); // 仍需的金额数
            float avgAddMoney = stillNeedMoney / moneyList.size(); // 平均每笔收入要增加的金额数
            for (int i = 0; i < moneyList.size(); i++) {
                float orginInt = moneyList.get(i);
                float newInt = orginInt + avgAddMoney;
                if (newInt > 100 && newInt < 10000) {
                    float dealInt = (newInt / 10) * 10;
                    moneyList.set(i, dealInt);
                }
                if (newInt > 10000) {
                    float dealInt = (newInt / 100) * 100;
                    moneyList.set(i, dealInt);
                }
            }
        }
        tempTotal = tempTotal + (tempTotal / 10); // 预期值的10%
        if (dealMoneyTotal > tempTotal) {
            log.info("验证总和: {} 大于预期金额的10%，则进行处理...", dealMoneyTotal);
            float stillNeedMoney = (dealMoneyTotal - tempTotal); // 多余的金额数
            float avgDivMoney = stillNeedMoney / moneyList.size(); // 平均每笔支出要减少的金额数
            for (int i = 0; i < moneyList.size(); i++) {
                float orginInt = moneyList.get(i);
                if (orginInt > avgDivMoney) {
                    float newInt = orginInt - avgDivMoney;
                    if (newInt > 100 && newInt < 10000) {
                        float dealInt = (newInt / 10) * 10;
                        moneyList.set(i, dealInt);
                    }
                    if (newInt > 10000) {
                        float dealInt = (newInt / 100) * 100;
                        moneyList.set(i, dealInt);
                    }
                }
            }
        }
        log.info("处理金额位数...");
        for (int i = 0; i < moneyList.size(); i++) {
            float orginMoney = moneyList.get(i);
            if (orginMoney > 100 && orginMoney < 10000) {
                float dealInt = (orginMoney / 10) * 10;
                moneyList.set(i, dealInt);
            }
            if (orginMoney > 10000) {
                float dealInt = (orginMoney / 100) * 100;
                moneyList.set(i, dealInt);
            }
        }
        log.info("处理结果：{}", Arrays.toString(moneyList.toArray()));
        float maxMoney = Collections.max(moneyList);
        log.info("处理结果最大值：{}", maxMoney);
        for (float x : moneyList) {
            check_num_two = check_num_two + x;
        }
        log.info("再次验证总和: {}", check_num_two + excludeMoney);
        for (float i : moneyList) {
            String moneyStr = StringUtils.equals(inOrOut, "收入") ? ("+" + i) : ("-" + i);
            moneyStrList.add(moneyStr);
        }
        return moneyList;
    }

}
